/**
 * @class	ConveyorTest
 *
 * @brief	Will test messages being sent by Conveyor Agent.
 *
 * @author	Erica Zhao
 */

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "ConveyorAgent.h"
#include "FactoryControlSystemAgentMock.h"
#include "Conveyor.h"
#include "Kit.h"
#include "KitMock.h"
#include "KitRecipe.h"
#include "Enums.h"
#include <string>
#include <iostream>

class ConveyorAgent;
class Kit;
class KitRecipe;

std::string ConveyorTestString = "Conveyor Test";

class ConveyorTest : public ::testing::Test 
{
public:

	//ConveyorAgent conveyor;

	ConveyorTest() 
		//: conveyor(ConveyorTestString)
	{
	}

	virtual void SetUp() 
	{
	}
};

TEST_F(ConveyorTest, initializationTest) 
{
	ConveyorAgent conveyor("Conveyor", ConveyorType::Conveyor_In);

	// All lists should initialize to 0.
	EXPECT_EQ(0, conveyor.kitRecipes.size());
	EXPECT_EQ(0, conveyor.finishedKits.size());

	// Nothing should be in the scheduler.
	EXPECT_FALSE(conveyor.pickAndExecuteAnAction());
}

TEST_F(ConveyorTest, msgHereAreKits) 
{
	KitMock *kit = new KitMock();
	KitRecipe *kitRecipe = new KitRecipe();

	ConveyorAgent conveyor("Conveyor", ConveyorType::Conveyor_In);

	EXPECT_FALSE(conveyor.pickAndExecuteAnAction());
	
	//// Conveyor's state should be None
	//EXPECT_EQ(ConveyorAgent::ConveyorAgentState::None, convState());

	// Send Conveyor the kits
	conveyor.msgHereAreKits(kitRecipe);

	// There should be a kit recipe inside the list kitRecipes
	EXPECT_EQ(1, conveyor.kitRecipes.size());

	//// Kit state should be WaitingForKitRobot
	//EXPECT_EQ(ConveyorAgent::KitState::WaitingForKitRobot, ConveyorAgent::MyKit::state);

	// Pick and Execute an Action should now return false.
	EXPECT_FALSE( conveyor.pickAndExecuteAnAction() );

}

TEST_F(ConveyorTest, msgHereIsFinishedKit) 
{
	KitMock *kit = new KitMock();
	InspectorKitState *kState = new InspectorKitState();
	KitInterface* k;

	ConveyorAgent conveyor("Conveyor", ConveyorType::Conveyor_OutGood);

	EXPECT_FALSE(conveyor.pickAndExecuteAnAction());

	// Give conveyor finished kit
	conveyor.msgHereIsFinishedKit(k);

	// There should be a kit recipe inside the list kitRecipes
	EXPECT_EQ(1, conveyor.finishedKits.size());

	// Pick and Execute an Action should now return true because state is changed.
	EXPECT_TRUE( conveyor.pickAndExecuteAnAction() );

	// Pick and Execute an Action should now return false.
	EXPECT_FALSE( conveyor.pickAndExecuteAnAction() );
}

TEST_F(ConveyorTest, msgKitEndOfConveyor) 
{
	KitMock *kit = new KitMock();

	ConveyorAgent conveyor("Conveyor", ConveyorType::Conveyor_OutGood);

	EXPECT_FALSE(conveyor.pickAndExecuteAnAction());

	// kit is at the end of the conveyor
	conveyor.msgKitEndOfConveyor((Kit*)kit);

	// Pick and Execute an Action should now return true because state is changed.
	EXPECT_TRUE( conveyor.pickAndExecuteAnAction() );

	// Pick and Execute an Action should now return false.
	EXPECT_FALSE( conveyor.pickAndExecuteAnAction() );
}